<!DOCTYPE html>
<html>
  <!-- meta/link... -->
  



<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
  <!-- Global site tag (gtag.js) - Google Analytics -->


  <title>Hbase介绍及操作 | symkmk123</title>

  <link rel="icon" type="image/x-icon, image/vnd.microsoft.icon" href="/favicon.ico">
  <link rel="stylesheet" href="https://at.alicdn.com/t/font_1911880_c1nvbyezg17.css">
  <link href="https://cdn.jsdelivr.net/gh/inkss/fontawesome@5.15.3/css/all.min.css" rel="stylesheet">

  
    <script>
        var themeModelId = '';
        if (themeModelId) {
            localStorage.setItem('modelId', themeModelId);
        }
    </script>
    
    <script src="https://cdn.jsdelivr.net/gh/yuang01/live2d-widget@latest/autoload.js"></script>
    <script>
        var live2dOpen = eval('true') || false;
        if (!live2dOpen) {
            localStorage.setItem('waifu-display', 1609323474481);
        }
    </script>
  
  
  
<link rel="stylesheet" href="/css/animate.min.css">

  
<link rel="stylesheet" href="/css/style.css">

  
  
    
<link rel="stylesheet" href="/js/fancybox/jquery.fancybox.min.css">

  
  
  <style>
        @media (max-width: 992px) {
            #waifu {
                display: none;
            }
        }
    </style>
    <script src="//cdn.bootcss.com/pace/1.0.2/pace.min.js"></script>
    <link href="//cdn.bootcss.com/pace/1.0.2/themes/pink/pace-theme-flash.css" rel="stylesheet">

    

    <!-- import link -->
    
        
            
        
            
        
    
    <!-- import script -->
    
        
            
        
            
        
    

<meta name="generator" content="Hexo 5.4.0"></head>

  
  <!-- 依赖于jquery和vue -->
  <script src="/js/jquery3.5.1.js"></script>
  <script src="/js/vue2.6.11.js"></script>
  
  <body>
    <!-- 预加载动画 -->
    <!-- 页面预加载动画 -->

<div id='loader'>
  <link rel="stylesheet" href="/js/loaded/index.css" >
  <div class="loading-left-bg"></div>
  <div class="loading-right-bg"></div>
  <div class="spinner-box">
    <div class="configure-border-1">
      <div class="configure-core"></div>
    </div>
    <div class="configure-border-2">
      <div class="configure-core"></div>
    </div>
    <div class="loading-word">加载中...</div>
  </div>
</div>

<script>
  var endLoading = function () {
    document.body.style.overflow = 'auto';
    document.getElementById('loader').classList.add("loading");
  }
  window.addEventListener('DOMContentLoaded',endLoading);
  
</script>

    
    <!-- 判断是否为暗黑风格 -->
    <!-- 判断是否为黑夜模式 -->
<script>
  let isDark = JSON.parse(localStorage.getItem('dark')) || JSON.parse('false');

  if (isDark) {
    $(document.body).addClass('darkModel');
  }
</script>

    <!-- 头部导航等 -->
    
<header class="header " id="navHeader"
  style="position: fixed;
  left: 0; top: 0; z-index: 10;width: 100%;"
>
  <div class="header-content">
    <div class="bars">
      <div id="appDrawer" class="sidebar-image">
  <div class="drawer-box-icon">
    <i class="fas fa-bars" aria-hidden="true" @click="showDialogDrawer"></i>
  </div>
  
  <transition name="fade">
    <div class="drawer-box_mask" v-cloak style="display: none;" v-show="visible" @click.self="cancelDialogDrawer">
    </div>
  </transition>
  <div class="drawer-box" :class="{'active': visible}">
    <div class="drawer-box-head bg-color">
      <img class="drawer-box-head_logo lazyload placeholder" src="/medias/logo.png" class="lazyload placeholder" data-srcset="/medias/logo.png" srcset="https://img2.baidu.com/it/u=2037979560,2772131037&fm=26&fmt=auto&gp=0.jpg" alt="logo">
      <h3 class="drawer-box-head_title">symkmk123</h3>
      <h5 class="drawer-box-head_desc"></h5>
    </div>
    
    <div class="drawer-box-content">
      <ul class="drawer-box-content_menu">
        
          
            <li class="drawer-box-content_item" style="position: relative;">
              
                <a href="/" class="drawer-menu-item-link">
                  
                    <i class="fa fa-home" aria-hidden="true"></i>
                  
                  <span class="name">首页</span>
                </a>
              
            </li>
          
            <li class="drawer-box-content_item" style="position: relative;">
              
                <a href="/archives" class="drawer-menu-item-link">
                  
                    <i class="fa fa-archive" aria-hidden="true"></i>
                  
                  <span class="name">归档</span>
                </a>
              
            </li>
          
            <li class="drawer-box-content_item" style="position: relative;">
              
                <a href="/tags" class="drawer-menu-item-link">
                  
                    <i class="fa fa-tags" aria-hidden="true"></i>
                  
                  <span class="name">标签</span>
                </a>
              
            </li>
          
            <li class="drawer-box-content_item" style="position: relative;">
              
                <a href="/categories" class="drawer-menu-item-link">
                  
                    <i class="fa fa-bookmark" aria-hidden="true"></i>
                  
                  <span class="name">分类</span>
                </a>
              
            </li>
          
            <li class="drawer-box-content_item" style="position: relative;">
              
                <a href="/about" class="drawer-menu-item-link">
                  
                    <i class="fa fa-user" aria-hidden="true"></i>
                  
                  <span class="name">关于</span>
                </a>
              
            </li>
          
        
        
          <li class="drawer-box-content_item">
            <a target="_blank" rel="noopener" href="https://gitee.com/symkmk123">
              <i class="fas fa-github" aria-hidden="true"></i>
              <span>Github</span>
            </a>
          </li>
        
      </ul>
    </div>
  </div>
</div>

<script>
  var body = document.body || document.documentElement || window;
  var vm = new Vue({
    el: '#appDrawer',
    data: {
      visible: false,
      top: 0,
      openArr: [],
    },
    computed: {
    },
    mounted() {
    },
    methods: {
      isOpen(index) {
        if (this.openArr.includes(index)) {
          return true;
        } else {
          return false;
        }
      },
      openOrCloseMenu(curIndex) {
        const index = this.openArr.indexOf(curIndex);
        if (index !== -1) {
          this.openArr.splice(index, 1);
        } else {
          this.openArr.push(curIndex);
        }
      },
      showDialogDrawer() {
        this.visible = true;
        // 防止页面滚动，只能让弹框滚动
        this.top = $(document).scrollTop()
        body.style.cssText = 'width: 100%; height: 100%;overflow: hidden;';
      },
      cancelDialogDrawer() {
        this.visible = false;
        body.removeAttribute('style');
        $(document).scrollTop(this.top)
      }
    },
    created() {}
  })
</script>

    </div>
    <div class="blog-title" id="author-avatar">
      
        <div class="avatar">
          <img src="/medias/logo.png" class="lazyload placeholder" data-srcset="/medias/logo.png" srcset="https://img2.baidu.com/it/u=2037979560,2772131037&fm=26&fmt=auto&gp=0.jpg" alt="logo">
        </div>
      
      <a href="/" class="logo">symkmk123</a>
    </div>
    <nav class="navbar">
      <ul class="menu">
        
          
            <li class="menu-item" style="position: relative;">
              
                <a href="/" class="menu-item-link" title="首页">
                  
                    <i class="fa fa-home" aria-hidden="true"></i>
                  
                  <span class="name">首页</span>
                </a>
              
            </li>
          
            <li class="menu-item" style="position: relative;">
              
                <a href="/archives" class="menu-item-link" title="归档">
                  
                    <i class="fa fa-archive" aria-hidden="true"></i>
                  
                  <span class="name">归档</span>
                </a>
              
            </li>
          
            <li class="menu-item" style="position: relative;">
              
                <a href="/tags" class="menu-item-link" title="标签">
                  
                    <i class="fa fa-tags" aria-hidden="true"></i>
                  
                  <span class="name">标签</span>
                </a>
              
            </li>
          
            <li class="menu-item" style="position: relative;">
              
                <a href="/categories" class="menu-item-link" title="分类">
                  
                    <i class="fa fa-bookmark" aria-hidden="true"></i>
                  
                  <span class="name">分类</span>
                </a>
              
            </li>
          
            <li class="menu-item" style="position: relative;">
              
                <a href="/about" class="menu-item-link" title="关于">
                  
                    <i class="fa fa-user" aria-hidden="true"></i>
                  
                  <span class="name">关于</span>
                </a>
              
            </li>
          
        
      </ul>
      
      
        <div id="appSearch">
  <div class="search"  @click="showDialog()"><i class="fas fa-search" aria-hidden="true"></i></div>
  <transition name="fade">
    <div class="message-box_wrapper" style="display: none;" v-cloak v-show="dialogVisible" @click.self="cancelDialogVisible()">
      <div class="message-box animated bounceInDown">
        <h2>
          <span>
            <i class="fas fa-search" aria-hidden="true"></i>
            <span class="title">本地搜索</span>
          </span>
          <i class="fas fa-times close" pointer style="float:right;" aria-hidden="true" @click.self="cancelDialogVisible()"></i>
        </h2>
        <form class="site-search-form">
          <input type="text"
            placeholder="请输入关键字"
            id="local-search-input" 
            @click="getSearchFile()"
            class="st-search-input"
            v-model="searchInput"
          />
        </form>
        <div class="result-wrapper">
          <div id="local-search-result" class="local-search-result-cls"></div>
        </div>
      </div>
    </div>
  </transition>
</div>
<script src="/js/local_search.js"></script>
<script>
  var body = document.body || document.documentElement || window;
  var vm = new Vue({
    el: '#appSearch',
    data: {
      dialogVisible: false,
      searchInput: '',
      top: 0,
    },
    computed: {
    },
    mounted() {
      window.addEventListener('pjax:complete', () => {
        this.cancelDialogVisible();
      })
    },
    methods: {
      showDialog() {
        this.dialogVisible = true;
        // 防止页面滚动，只能让弹框滚动
        this.top = $(document).scrollTop()
        body.style.cssText = 'overflow: hidden;';
      },
      getSearchFile() {
        if (!this.searchInput) {
          getSearchFile("/search.xml");
        }
      },
      cancelDialogVisible() {
        this.dialogVisible = false;
        body.removeAttribute('style');
        $(document).scrollTop(this.top)
      },
    },
    created() {}
  })
</script>
<!-- 解决刷新页面闪烁问题，可以在元素上添加display: none, 或者用vue.extend方法，详情：https://blog.csdn.net/qq_31393401/article/details/81017912 -->
<!-- 下面是搜索基本写法 -->
<!-- <script type="text/javascript" id="local.search.active">
  var inputArea = document.querySelector("#local-search-input");
  inputArea.onclick   = function(){ getSearchFile(); this.onclick = null }
  inputArea.onkeydown = function(){ if(event.keyCode == 13) return false }
</script> -->

      

    </nav>
  </div>
  
    <a target="_blank" rel="noopener" href="https://gitee.com/symkmk123" class="github-corner color-primary" aria-label="View source on GitHub"><svg width="60" height="60" viewBox="0 0 250 250" style="fill:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
  
  

    <!-- 当头部导航设置为背景透明的时候  -->
    
      <script src="/js/header/index.js" data-pjax></script>
    
</header>

    <!-- 需要在上面加载的js -->
    <script>
  function loadScript(src, cb) {
    return new Promise(resolve => {
      setTimeout(function () {
        var HEAD = document.getElementsByTagName("head")[0] || document.documentElement;
        var script = document.createElement("script");
        script.setAttribute("type", "text/javascript");
        if (cb) {
          if (JSON.stringify(cb)) {
            for (let p in cb) {
              if (p == "onload") {
                script[p] = () => {
                  cb[p]()
                  resolve()
                }
              } else {
                script[p] = cb[p]
                script.onload = resolve
              }
            }
          } else {
            script.onload = () => {
              cb()
              resolve()
            };
          }
        } else {
          script.onload = resolve
        }
        script.setAttribute("src", src);
        HEAD.appendChild(script);
      });
    });
  }

  //https://github.com/filamentgroup/loadCSS
  var loadCSS = function (href, before, media, attributes) {
    return new Promise(resolve => {
      setTimeout(function () {
        var link = document.createElement('link');
        link.rel = "stylesheet";
        link.href = src;
        link.onload = resolve;
        document.getElementsByTagName("head")[0].appendChild(link);
      });
    });
  };

</script> 

<!-- 轮播图所需要的js -->
<script src="/js/swiper/swiper.min.js"></script>
<script src="/js/swiper/vue-awesome-swiper.js"></script>
<script src="/js/swiper/swiper.animate1.0.3.min.js"></script>


  <script src="/js/vue-typed-js/index.js"></script>


<!-- 首页的公告滚动插件的js需要重新加载 -->
<script src="/js/vue-seamless-scroll/index.js"></script>

<!-- 打字机效果js -->
<script src="https://cdn.jsdelivr.net/npm/typed.js@2.0.11"></script>


    <!-- 内容区域 -->
    <div id="safearea">
      <main class="main" id="pjax-container" style="margin-top: 0;">
        
 <!-- prismjs 代码高亮 -->
 


<div class="bg-dark-floor" style="position: fixed;left: 0;top: 0;width: 100%;height: 100%;z-index: -1;"></div>

<!-- 文章详情页顶部图片和标题 -->




<div class="post-detail-header" id="thumbnail_canvas" style="background-repeat: no-repeat; background-size: cover; 
  background-position: center center;position: relative;background-image:url('/medias/10.jpg')">
  <div class="post-detail-header-mask"></div>
  <canvas id="header_canvas"style="position:absolute;bottom:0;pointer-events:none;"></canvas>
  
  <div class="post-detail-header_info-box">
    <div class="title-box">
      <span class="title">
        Hbase介绍及操作
      </span>
    </div>
    
    
      
        <span class="post-detail-header_date">
          <i class="fas fa-calendar"></i> 发表于：2021-05-21 |
        </span>
      

      
        <span class="post-detail-header_categories">
          <i class="iconfont iconbookmark1"></i> 分类：
          
            <a href="/categories/%E5%A4%A7%E6%95%B0%E6%8D%AE/" class="post-detail-header_category">
              大数据
            </a>
          
        </span>
      

      
        <div class="post-detail-header_wordcount">
          <span class="totalcount">
            <i class="fas fa-file-text-o"></i> 字数统计: 3.3k |
          </span>
  
          <span class="min2read">
            <i class="fas fa-clock"></i> 阅读时长: 16分钟 |
          </span>
  
          
            <span class="reading">
              <i class="fas fa-eye"></i> 阅读量：<span id="busuanzi_value_page_pv"></span>
            </span>
          
        </div>
      
    
  </div>
  
  
    <script src="/js/bubble/bubble.js"></script>
  
</div>



<div class="row justify-position">
  <div class="main-content">
    <article class="post post-detail">
      <div class="post-content">
        <h1 id="1-Hbase概述"><a href="#1-Hbase概述" class="headerlink" title="1. Hbase概述"></a>1. Hbase概述</h1><h2 id="1-1-Hbase是什么"><a href="#1-1-Hbase是什么" class="headerlink" title="1.1 Hbase是什么"></a>1.1 Hbase是什么</h2><ul>
<li>HBase是建立在HDFS之上的分布式面向列的数据库；属于KV结构数据，原生不支持标准SQL。它是一个Apache的开源项目，是横向扩展的。</li>
<li>HBase可以提供快速随机访问海量结构化数据。它利用了Hadoop的文件系统（HDFS）提供的容错能力。</li>
<li>HBase不同于一般的关系数据库，它是一个适合于非结构化数据存储的数据库，是HBase基于列的而不是基于行的模式。</li>
</ul>
<h2 id="1-2-Hbase数据单元"><a href="#1-2-Hbase数据单元" class="headerlink" title="1.2 Hbase数据单元"></a>1.2 Hbase数据单元</h2><p>RowKey：是Byte array，是表中每条记录的“主键”，按照字典顺序排序，方便快速查找，Rowkey的设计非常重要；<br>Column Family：列族，拥有一个名称(string)，包含一个或者多个相关列；<br>Column：属于某一个columnfamily，familyName:columnName，每条记录可动态添加；<br>Version Number：类型为Long，默认值是系统时间戳Timestamp，可由用户自定义；用于标记同一份数据的不同版本。<br>Value(Cell)：Byte array；<br><img src="https://gitee.com/symkmk123/pic-go/raw/master/img/20210622161949.png" class="lazyload placeholder" data-srcset="https://gitee.com/symkmk123/pic-go/raw/master/img/20210622161949.png" srcset="https://img2.baidu.com/it/u=2037979560,2772131037&fm=26&fmt=auto&gp=0.jpg"></p>
<h1 id="2-Hbase的架构"><a href="#2-Hbase的架构" class="headerlink" title="2. Hbase的架构"></a>2. Hbase的架构</h1><h2 id="2-1-Hbase的架构组成"><a href="#2-1-Hbase的架构组成" class="headerlink" title="2.1 Hbase的架构组成"></a>2.1 Hbase的架构组成</h2><p>HBase采用Master/Slave架构搭建集群，它隶属于Hadoop生态系统，由以下类型节点组成：HMaster节点、HRegionServer节点、ZooKeeper集群，而在底层，它将数据存储于HDFS中，因而涉及到HDFS的NameNode、DataNode等，总体结构如下：<br><img src="https://gitee.com/symkmk123/pic-go/raw/master/img/20210622162244.png" class="lazyload placeholder" data-srcset="https://gitee.com/symkmk123/pic-go/raw/master/img/20210622162244.png" srcset="https://img2.baidu.com/it/u=2037979560,2772131037&fm=26&fmt=auto&gp=0.jpg"> </p>
<p>各组件说明:<br><strong>Client</strong></p>
<ul>
<li>使用HBase RPC机制与HMaster和HRegionServer进行通信；</li>
<li>Client与HMaster进行通信进行管理类操作；</li>
<li>Client与HRegionServer进行数据读写类操作；</li>
</ul>
<p><strong>HMaster</strong></p>
<ul>
<li>HMaster没有单点问题，HBase中可以启动多个HMaster，通过Zookeeper保证总有一个Master在运行。</li>
</ul>
<p><strong>HMaster主要负责Table和Region的管理工作</strong></p>
<ul>
<li>管理用户对表的增删改查操作；</li>
<li>管理HRegionServer的负载均衡，调整Region分布；</li>
<li>Region Split后，负责新Region的分布；</li>
<li>在HRegionServer停机后，负责失效HRegionServer上Region 的迁移；</li>
</ul>
<p><strong>HRegionServer</strong><br>HBase中最核心的模块；</p>
<ul>
<li>维护region，处理对这些region的IO请求；</li>
<li>Regionserver负责切分在运行过程中变得过大的region；</li>
</ul>
<p><strong>HRegion</strong></p>
<ul>
<li>HBase使用RowKey将表水平切割成多个HRegion，从HMaster的角度，每个HRegion都纪录了它的StartKey和EndKey（第一个HRegion的StartKey为空，最后一个HRegion的EndKey为空），由于RowKey是排序的，因而Client可以通过HMaster快速的定位每个RowKey在哪个HRegion中。</li>
</ul>
<h2 id="2-2查看hbase的web界面"><a href="#2-2查看hbase的web界面" class="headerlink" title="2.2查看hbase的web界面"></a>2.2查看hbase的web界面</h2><p><a target="_blank" rel="noopener" href="http://master:16010/">http://master:16010/</a></p>
<h1 id="3-hbase-shell操作"><a href="#3-hbase-shell操作" class="headerlink" title="3.hbase shell操作"></a>3.hbase shell操作</h1><h2 id="3-1-DDL操作"><a href="#3-1-DDL操作" class="headerlink" title="3.1 DDL操作"></a>3.1 DDL操作</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash">开启hbase shell</span></span><br><span class="line">hbase shell</span><br><span class="line"><span class="meta">#</span><span class="bash">查看hbase状态</span></span><br><span class="line">status</span><br><span class="line"><span class="meta">#</span><span class="bash">查看hbase版本</span></span><br><span class="line">version</span><br><span class="line"><span class="meta">#</span><span class="bash">创建命名空间</span></span><br><span class="line">create_namespace &#x27;命名空间名&#x27;</span><br><span class="line"><span class="meta">#</span><span class="bash">显示所有命名空间</span></span><br><span class="line">list_namespace</span><br><span class="line"><span class="meta">#</span><span class="bash">删除命名空间, 在删除一个命名空间时，该命名空间不能包含任何的表，否则会报错</span></span><br><span class="line">drop_namespace &#x27;命名空间名&#x27;</span><br><span class="line"><span class="meta">#</span><span class="bash">创建默认命名空间的表</span></span><br><span class="line">create &#x27;表名称&#x27;, &#x27;列族名称1&#x27;,&#x27;列族名称2&#x27;,&#x27;列族名称N&#x27;</span><br><span class="line"><span class="meta">#</span><span class="bash">创建带有命名空间的表</span></span><br><span class="line">create &#x27;命名空间:表名称&#x27;, &#x27;列族名称1&#x27;,&#x27;列族名称2&#x27;,&#x27;列族名称N&#x27;</span><br><span class="line"><span class="meta">#</span><span class="bash">列出所有表</span></span><br><span class="line">list</span><br><span class="line"><span class="meta">#</span><span class="bash">获得表的描述</span></span><br><span class="line">describe &#x27;表名&#x27;</span><br><span class="line"><span class="meta">#</span><span class="bash">删除table 表的 列族名称1 列族</span></span><br><span class="line">alter &#x27;table&#x27;,&#123;NAME=&gt;&#x27;列族名称1&#x27;,METHOD=&gt;&#x27;delete&#x27;&#125;</span><br><span class="line"><span class="meta">#</span><span class="bash">删除多个列族</span></span><br><span class="line">alter &#x27;table&#x27;, &#123;NAME =&gt; &#x27;列族名称1&#x27;, METHOD =&gt; &#x27;delete&#x27;&#125;,&#123;NAME =&gt; &#x27;列族名称2&#x27;, METHOD =&gt; &#x27;delete&#x27;&#125;</span><br><span class="line"><span class="meta">#</span><span class="bash">先把表下线</span></span><br><span class="line">disable &#x27;表名&#x27;</span><br><span class="line"><span class="meta">#</span><span class="bash">再drop表</span></span><br><span class="line">drop &#x27;表名&#x27;</span><br></pre></td></tr></table></figure>
<h2 id="3-2-DML操作"><a href="#3-2-DML操作" class="headerlink" title="3.2 DML操作"></a>3.2 DML操作</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash">添加数据</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 语法：put &lt;table&gt;,&lt;rowkey&gt;,&lt;family:column&gt;,&lt;value&gt;,[&lt;timestamp&gt;]</span></span><br><span class="line"><span class="meta">#</span><span class="bash">如果不写timestamp，则系统默认</span></span><br><span class="line">put &#x27;table&#x27;,&#x27;id01&#x27;, &#x27;c_f1:name&#x27;,&#x27;111&#x27;</span><br><span class="line"><span class="meta"></span></span><br><span class="line"><span class="meta">#</span><span class="bash">获取数据</span></span><br><span class="line"><span class="meta">#</span><span class="bash">get： 获取表中一行数据，不能扫描全表</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 语法：get &lt;table&gt;,&lt;rowkey&gt;,[&lt;family:column&gt;,....]</span></span><br><span class="line">get &#x27;table&#x27;,&#x27;id01&#x27;</span><br><span class="line"><span class="meta"></span></span><br><span class="line"><span class="meta">#</span><span class="bash">更新数据</span></span><br><span class="line"><span class="meta">#</span><span class="bash">语法：重新put，put时会覆盖原来的数据</span></span><br><span class="line">put &#x27;table&#x27;,&#x27;id01&#x27;, &#x27;c_f1:name&#x27;,&#x27;222&#x27;</span><br><span class="line"><span class="meta"></span></span><br><span class="line"><span class="meta">#</span><span class="bash">scan扫描</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 语法：scan &lt;table&gt; ,&#123;COLUMNS =&gt; [ &lt;family:column&gt;,.... ], LIMIT =&gt; num&#125;</span></span><br><span class="line"><span class="meta">#</span><span class="bash">扫描全表，大表操作不可取</span></span><br><span class="line">scan &#x27;table&#x27;</span><br><span class="line"><span class="meta">#</span><span class="bash">获取表中前两行</span></span><br><span class="line">scan &#x27;table&#x27;, &#123;LIMIT =&gt; 2&#125;</span><br><span class="line"><span class="meta">#</span><span class="bash">扫描表中指定列族数据</span></span><br><span class="line">scan &#x27;table&#x27;, &#123;COLUMNS =&gt; &#x27;c_f1&#x27;&#125;</span><br><span class="line"><span class="meta">#</span><span class="bash">扫描表中执行列族中列的数据</span></span><br><span class="line">scan &#x27;table&#x27;, &#123;COLUMNS =&gt; &#x27;c_f2:cert_no&#x27;&#125;</span><br><span class="line"><span class="meta">#</span><span class="bash">扫描表中值=222 的数据</span></span><br><span class="line">scan &#x27;table&#x27;, FILTER=&gt;&quot;ValueFilter(=,&#x27;name:222&#x27;)&quot;</span><br><span class="line"><span class="meta">#</span><span class="bash"> 筛选行，按照rowkey的范围[STARTROW,STOPROW)</span> </span><br><span class="line">scan &#x27;table&#x27;, &#123;STARTROW =&gt;&#x27;id01&#x27; , STOPROW =&gt; &#x27;id03&#x27;&#125;</span><br><span class="line"><span class="meta"></span></span><br><span class="line"><span class="meta">#</span><span class="bash">删除行中某列数据</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 语法：delete &lt;table&gt;, &lt;rowkey&gt;, &lt;family:column&gt;</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 必须指定列名</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 会删除执行列的所有版本数据</span></span><br><span class="line">delete &#x27;table&#x27;, &#x27;id04&#x27;,  &#x27;c_f2:name&#x27;</span><br><span class="line"><span class="meta"></span></span><br><span class="line"><span class="meta">#</span><span class="bash">删除整行</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 语法：deleteall &lt;table&gt;, &lt;rowkey&gt;</span></span><br><span class="line">deleteall &#x27;table&#x27;, &#x27;id05&#x27;</span><br><span class="line"><span class="meta"></span></span><br><span class="line"><span class="meta">#</span><span class="bash">清空表数据</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 语法： truncate &lt;table&gt;</span></span><br><span class="line">truncate &#x27;table&#x27;</span><br><span class="line"><span class="meta"></span></span><br><span class="line"><span class="meta">#</span><span class="bash">查询表中有多少行</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 语法：count &lt;table&gt;, &#123;INTERVAL =&gt; intervalNum, CACHE =&gt; cacheNum&#125;</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> INTERVAL设置多少行显示一次及对应的rowkey，默认1000；</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> CACHE每次去取的缓存区大小，默认是10，调整该参数可提高查询速度</span></span><br><span class="line"><span class="meta">#</span><span class="bash">查询表中数据行数</span></span><br><span class="line">count &#x27;table&#x27;</span><br><span class="line"><span class="meta">#</span><span class="bash">按照2行显示一次，查询</span></span><br><span class="line">count &#x27;table&#x27;, &#123;INTERVAL =&gt; 2&#125; </span><br></pre></td></tr></table></figure>
<h1 id="4-hbase整合springboot"><a href="#4-hbase整合springboot" class="headerlink" title="4.hbase整合springboot"></a>4.hbase整合springboot</h1><h2 id="4-1pom"><a href="#4-1pom" class="headerlink" title="4.1pom"></a>4.1pom</h2><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.apache.hbase<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>hbase-client<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>1.3.6<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h2 id="4-2-application-properties"><a href="#4-2-application-properties" class="headerlink" title="4.2 application.properties"></a>4.2 application.properties</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hbase.conf.confMaps.&#x27;hbase.zookeeper.quorum&#x27;=master,slave1,slave2</span><br></pre></td></tr></table></figure>
<h2 id="4-3-HbaseConfig-自定义配置类"><a href="#4-3-HbaseConfig-自定义配置类" class="headerlink" title="4.3 HbaseConfig 自定义配置类"></a>4.3 HbaseConfig 自定义配置类</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> org.springframework.boot.context.properties.ConfigurationProperties;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Configuration;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.Map;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Hbase-Conf配置</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: suyuan</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="meta">@ConfigurationProperties(prefix = HbaseConfig.CONF_PREFIX)</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HbaseConfig</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> String CONF_PREFIX = <span class="string">&quot;hbase.conf&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> Map&lt;String,String&gt; confMaps;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Map&lt;String, String&gt; <span class="title">getconfMaps</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> confMaps;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setconfMaps</span><span class="params">(Map&lt;String, String&gt; confMaps)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.confMaps = confMaps;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="4-4-HBaseUtils工具类"><a href="#4-4-HBaseUtils工具类" class="headerlink" title="4.4 HBaseUtils工具类"></a>4.4 HBaseUtils工具类</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> org.springframework.beans.BeansException;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.ApplicationContext;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.ApplicationContextAware;</span><br><span class="line"><span class="keyword">import</span> org.springframework.stereotype.Component;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Spring的ApplicationContext的持有者,可以用静态方法的方式获取spring容器中的bean</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SpringContextHolder</span> <span class="keyword">implements</span> <span class="title">ApplicationContextAware</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> ApplicationContext applicationContext;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setApplicationContext</span><span class="params">(ApplicationContext applicationContext)</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">        SpringContextHolder.applicationContext = applicationContext;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> ApplicationContext <span class="title">getApplicationContext</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        assertApplicationContext();</span><br><span class="line">        <span class="keyword">return</span> applicationContext;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@SuppressWarnings(&quot;unchecked&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> &lt;T&gt; <span class="function">T <span class="title">getBean</span><span class="params">(String beanName)</span> </span>&#123;</span><br><span class="line">        assertApplicationContext();</span><br><span class="line">        <span class="keyword">return</span> (T) applicationContext.getBean(beanName);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> &lt;T&gt; <span class="function">T <span class="title">getBean</span><span class="params">(Class&lt;T&gt; requiredType)</span> </span>&#123;</span><br><span class="line">        assertApplicationContext();</span><br><span class="line">        <span class="keyword">return</span> applicationContext.getBean(requiredType);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">assertApplicationContext</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (SpringContextHolder.applicationContext == <span class="keyword">null</span>) &#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> RuntimeException(<span class="string">&quot;applicaitonContext属性为null,请检查是否注入了SpringContextHolder!&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> org.apache.hadoop.conf.Configuration;</span><br><span class="line"><span class="keyword">import</span> org.apache.hadoop.hbase.*;</span><br><span class="line"><span class="keyword">import</span> org.apache.hadoop.hbase.client.*;</span><br><span class="line"><span class="keyword">import</span> org.apache.hadoop.hbase.client.coprocessor.AggregationClient;</span><br><span class="line"><span class="keyword">import</span> org.apache.hadoop.hbase.client.coprocessor.LongColumnInterpreter;</span><br><span class="line"><span class="keyword">import</span> org.apache.hadoop.hbase.filter.*;</span><br><span class="line"><span class="keyword">import</span> org.apache.hadoop.hbase.util.Bytes;</span><br><span class="line"><span class="keyword">import</span> org.slf4j.Logger;</span><br><span class="line"><span class="keyword">import</span> org.slf4j.LoggerFactory;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.DependsOn;</span><br><span class="line"><span class="keyword">import</span> org.springframework.stereotype.Component;</span><br><span class="line"><span class="keyword">import</span> org.springframework.util.StopWatch;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"><span class="keyword">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"><span class="keyword">import</span> java.util.Map;</span><br><span class="line"><span class="keyword">import</span> java.util.NavigableMap;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.ExecutorService;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.Executors;</span><br><span class="line"></span><br><span class="line"><span class="meta">@DependsOn(&quot;springContextHolder&quot;)</span>        <span class="comment">//控制依赖顺序，保证springContextHolder类在之前已经加载</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HBaseUtils</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> Logger logger = LoggerFactory.getLogger(<span class="keyword">this</span>.getClass());</span><br><span class="line"></span><br><span class="line">    <span class="comment">//手动获取hbaseConfig配置类对象</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> HbaseConfig hbaseConfig = SpringContextHolder.getBean(<span class="string">&quot;hbaseConfig&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> Configuration conf = HBaseConfiguration.create();</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> ExecutorService pool = Executors.newScheduledThreadPool(<span class="number">20</span>);    <span class="comment">//设置连接池</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> Connection connection = <span class="keyword">null</span>;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> HBaseUtils instance = <span class="keyword">null</span>;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> Admin admin = <span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="title">HBaseUtils</span><span class="params">()</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(connection == <span class="keyword">null</span>)&#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                <span class="comment">//将hbase配置类中定义的配置加载到连接池中每个连接里</span></span><br><span class="line">                Map&lt;String, String&gt; confMap = hbaseConfig.getconfMaps();</span><br><span class="line">                <span class="keyword">for</span> (Map.Entry&lt;String,String&gt; confEntry : confMap.entrySet()) &#123;</span><br><span class="line">                    conf.set(confEntry.getKey(), confEntry.getValue());</span><br><span class="line">                &#125;</span><br><span class="line">                connection = ConnectionFactory.createConnection(conf, pool);</span><br><span class="line">                admin = connection.getAdmin();</span><br><span class="line">            &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">                logger.error(<span class="string">&quot;HbaseUtils实例初始化失败！错误信息为：&quot;</span> + e.getMessage(), e);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//简单单例方法，如果autowired自动注入就不需要此方法</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">synchronized</span> HBaseUtils <span class="title">getInstance</span><span class="params">()</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(instance == <span class="keyword">null</span>)&#123;</span><br><span class="line">            instance = <span class="keyword">new</span> HBaseUtils();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> instance;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 创建表</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> tableName         表名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> columnFamily      列族（数组）</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">createTable</span><span class="params">(String tableName, String[] columnFamily)</span> <span class="keyword">throws</span> IOException</span>&#123;</span><br><span class="line">        TableName name = TableName.valueOf(tableName);</span><br><span class="line">        <span class="comment">//如果存在则删除</span></span><br><span class="line">        <span class="keyword">if</span> (admin.tableExists(name)) &#123;</span><br><span class="line">            admin.disableTable(name);</span><br><span class="line">            admin.deleteTable(name);</span><br><span class="line">            logger.error(<span class="string">&quot;create htable error! this table &#123;&#125; already exists!&quot;</span>, name);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            HTableDescriptor desc = <span class="keyword">new</span> HTableDescriptor(name);</span><br><span class="line">            <span class="keyword">for</span> (String cf : columnFamily) &#123;</span><br><span class="line">                desc.addFamily(<span class="keyword">new</span> HColumnDescriptor(cf));</span><br><span class="line">            &#125;</span><br><span class="line">            admin.createTable(desc);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 插入记录（单行单列族-多列多值）</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> tableName         表名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> row               行名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> columnFamilys     列族名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> columns           列名（数组）</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> values            值（数组）（且需要和列一一对应）</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">insertRecords</span><span class="params">(String tableName, String row, String columnFamilys, String[] columns, String[] values)</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">        TableName name = TableName.valueOf(tableName);</span><br><span class="line">        Table table = connection.getTable(name);</span><br><span class="line">        Put put = <span class="keyword">new</span> Put(Bytes.toBytes(row));</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; columns.length; i++) &#123;</span><br><span class="line">            put.addColumn(Bytes.toBytes(columnFamilys), Bytes.toBytes(columns[i]), Bytes.toBytes(values[i]));</span><br><span class="line">            table.put(put);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 插入记录（单行单列族-单列单值）</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> tableName         表名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> row               行名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> columnFamily      列族名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> column            列名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> value             值</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">insertOneRecord</span><span class="params">(String tableName, String row, String columnFamily, String column, String value)</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">        TableName name = TableName.valueOf(tableName);</span><br><span class="line">        Table table = connection.getTable(name);</span><br><span class="line">        Put put = <span class="keyword">new</span> Put(Bytes.toBytes(row));</span><br><span class="line">        put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(column), Bytes.toBytes(value));</span><br><span class="line">        table.put(put);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 删除一行记录</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> tablename         表名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> rowkey            行名</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">deleteRow</span><span class="params">(String tablename, String rowkey)</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">        TableName name = TableName.valueOf(tablename);</span><br><span class="line">        Table table = connection.getTable(name);</span><br><span class="line">        Delete d = <span class="keyword">new</span> Delete(rowkey.getBytes());</span><br><span class="line">        table.delete(d);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 删除单行单列族记录</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> tablename         表名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> rowkey            行名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> columnFamily      列族名</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">deleteColumnFamily</span><span class="params">(String tablename, String rowkey, String columnFamily)</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">        TableName name = TableName.valueOf(tablename);</span><br><span class="line">        Table table = connection.getTable(name);</span><br><span class="line">        Delete d = <span class="keyword">new</span> Delete(rowkey.getBytes()).deleteFamily(Bytes.toBytes(columnFamily));</span><br><span class="line">        table.delete(d);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 删除单行单列族单列记录</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> tablename         表名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> rowkey            行名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> columnFamily      列族名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> column            列名</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">deleteColumn</span><span class="params">(String tablename, String rowkey, String columnFamily, String column)</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">        TableName name = TableName.valueOf(tablename);</span><br><span class="line">        Table table = connection.getTable(name);</span><br><span class="line">        Delete d = <span class="keyword">new</span> Delete(rowkey.getBytes()).deleteColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(column));</span><br><span class="line">        table.delete(d);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 查找一行记录</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> tablename         表名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> rowKey            行名</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> String <span class="title">selectRow</span><span class="params">(String tablename, String rowKey)</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">        String record = <span class="string">&quot;&quot;</span>;</span><br><span class="line">        TableName name=TableName.valueOf(tablename);</span><br><span class="line">        Table table = connection.getTable(name);</span><br><span class="line">        Get g = <span class="keyword">new</span> Get(rowKey.getBytes());</span><br><span class="line">        Result rs = table.get(g);</span><br><span class="line">        NavigableMap&lt;<span class="keyword">byte</span>[], NavigableMap&lt;<span class="keyword">byte</span>[], NavigableMap&lt;Long, <span class="keyword">byte</span>[]&gt;&gt;&gt; map = rs.getMap();</span><br><span class="line">        <span class="keyword">for</span> (Cell cell : rs.rawCells()) &#123;</span><br><span class="line">            StringBuffer stringBuffer = <span class="keyword">new</span> StringBuffer().append(Bytes.toString(cell.getRow())).append(<span class="string">&quot;\t&quot;</span>)</span><br><span class="line">                    .append(Bytes.toString(cell.getFamily())).append(<span class="string">&quot;\t&quot;</span>)</span><br><span class="line">                    .append(Bytes.toString(cell.getQualifier())).append(<span class="string">&quot;\t&quot;</span>)</span><br><span class="line">                    .append(Bytes.toString(cell.getValue())).append(<span class="string">&quot;\n&quot;</span>);</span><br><span class="line">            String str = stringBuffer.toString();</span><br><span class="line">            record += str;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> record;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 查找单行单列族单列记录</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> tablename         表名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> rowKey            行名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> columnFamily      列族名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> column            列名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> String <span class="title">selectValue</span><span class="params">(String tablename, String rowKey, String columnFamily, String column)</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">        TableName name=TableName.valueOf(tablename);</span><br><span class="line">        Table table = connection.getTable(name);</span><br><span class="line">        Get g = <span class="keyword">new</span> Get(rowKey.getBytes());</span><br><span class="line">        g.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(column));</span><br><span class="line">        Result rs = table.get(g);</span><br><span class="line">        <span class="keyword">return</span> Bytes.toString(rs.value());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 查询表中所有行（Scan方式）</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> tablename</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">scanAllRecord</span><span class="params">(String tablename)</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">        String record = <span class="string">&quot;&quot;</span>;</span><br><span class="line">        TableName name=TableName.valueOf(tablename);</span><br><span class="line">        Table table = connection.getTable(name);</span><br><span class="line">        Scan scan = <span class="keyword">new</span> Scan();</span><br><span class="line">        ResultScanner scanner = table.getScanner(scan);</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">for</span>(Result result : scanner)&#123;</span><br><span class="line">                <span class="keyword">for</span> (Cell cell : result.rawCells()) &#123;</span><br><span class="line">                    StringBuffer stringBuffer = <span class="keyword">new</span> StringBuffer().append(Bytes.toString(cell.getRow())).append(<span class="string">&quot;\t&quot;</span>)</span><br><span class="line">                            .append(Bytes.toString(cell.getFamily())).append(<span class="string">&quot;\t&quot;</span>)</span><br><span class="line">                            .append(Bytes.toString(cell.getQualifier())).append(<span class="string">&quot;\t&quot;</span>)</span><br><span class="line">                            .append(Bytes.toString(cell.getValue())).append(<span class="string">&quot;\n&quot;</span>);</span><br><span class="line">                    String str = stringBuffer.toString();</span><br><span class="line">                    record += str;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> (scanner != <span class="keyword">null</span>) &#123;</span><br><span class="line">                scanner.close();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> record;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 根据rowkey关键字查询报告记录</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> tablename</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> rowKeyword</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> List <span class="title">scanReportDataByRowKeyword</span><span class="params">(String tablename, String rowKeyword)</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">        ArrayList&lt;Object&gt; list = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line">        Table table = connection.getTable(TableName.valueOf(tablename));</span><br><span class="line">        Scan scan = <span class="keyword">new</span> Scan();</span><br><span class="line"></span><br><span class="line">        <span class="comment">//添加行键过滤器，根据关键字匹配</span></span><br><span class="line">        RowFilter rowFilter = <span class="keyword">new</span> RowFilter(CompareFilter.CompareOp.EQUAL, <span class="keyword">new</span> SubstringComparator(rowKeyword));</span><br><span class="line">        scan.setFilter(rowFilter);</span><br><span class="line"></span><br><span class="line">        ResultScanner scanner = table.getScanner(scan);</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">for</span> (Result result : scanner) &#123;</span><br><span class="line">                <span class="comment">//TODO 此处根据业务来自定义实现</span></span><br><span class="line">                list.add(<span class="keyword">null</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> (scanner != <span class="keyword">null</span>) &#123;</span><br><span class="line">                scanner.close();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> list;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 根据rowkey关键字和时间戳范围查询报告记录</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> tablename</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> rowKeyword</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> List <span class="title">scanReportDataByRowKeywordTimestamp</span><span class="params">(String tablename, String rowKeyword, Long minStamp, Long maxStamp)</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">        ArrayList&lt;Object&gt; list = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line">        Table table = connection.getTable(TableName.valueOf(tablename));</span><br><span class="line">        Scan scan = <span class="keyword">new</span> Scan();</span><br><span class="line">        <span class="comment">//添加scan的时间范围</span></span><br><span class="line">        scan.setTimeRange(minStamp, maxStamp);</span><br><span class="line"></span><br><span class="line">        RowFilter rowFilter = <span class="keyword">new</span> RowFilter(CompareFilter.CompareOp.EQUAL, <span class="keyword">new</span> SubstringComparator(rowKeyword));</span><br><span class="line">        scan.setFilter(rowFilter);</span><br><span class="line"></span><br><span class="line">        ResultScanner scanner = table.getScanner(scan);</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">for</span> (Result result : scanner) &#123;</span><br><span class="line">                <span class="comment">//TODO 此处根据业务来自定义实现</span></span><br><span class="line">                list.add(<span class="keyword">null</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> (scanner != <span class="keyword">null</span>) &#123;</span><br><span class="line">                scanner.close();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> list;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 删除表操作</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> tablename</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">deleteTable</span><span class="params">(String tablename)</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">        TableName name=TableName.valueOf(tablename);</span><br><span class="line">        <span class="keyword">if</span>(admin.tableExists(name)) &#123;</span><br><span class="line">            admin.disableTable(name);</span><br><span class="line">            admin.deleteTable(name);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 利用协处理器进行全表count统计</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> tablename</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Long <span class="title">countRowsWithCoprocessor</span><span class="params">(String tablename)</span> <span class="keyword">throws</span> Throwable </span>&#123;</span><br><span class="line">        TableName name=TableName.valueOf(tablename);</span><br><span class="line">        HTableDescriptor descriptor = admin.getTableDescriptor(name);</span><br><span class="line"></span><br><span class="line">        String coprocessorClass = <span class="string">&quot;org.apache.hadoop.hbase.coprocessor.AggregateImplementation&quot;</span>;</span><br><span class="line">        <span class="keyword">if</span> (! descriptor.hasCoprocessor(coprocessorClass)) &#123;</span><br><span class="line">            admin.disableTable(name);</span><br><span class="line">            descriptor.addCoprocessor(coprocessorClass);</span><br><span class="line">            admin.modifyTable(name, descriptor);</span><br><span class="line">            admin.enableTable(name);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//计时</span></span><br><span class="line">        StopWatch stopWatch = <span class="keyword">new</span> StopWatch();</span><br><span class="line">        stopWatch.start();</span><br><span class="line"></span><br><span class="line">        Scan scan = <span class="keyword">new</span> Scan();</span><br><span class="line">        AggregationClient aggregationClient = <span class="keyword">new</span> AggregationClient(conf);</span><br><span class="line"></span><br><span class="line">        Long count = aggregationClient.rowCount(name, <span class="keyword">new</span> LongColumnInterpreter(), scan);</span><br><span class="line"></span><br><span class="line">        stopWatch.stop();</span><br><span class="line">        System.out.println(<span class="string">&quot;RowCount：&quot;</span> + count +  <span class="string">&quot;，全表count统计耗时：&quot;</span> + stopWatch.getTotalTimeMillis());</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> count;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="4-5-测试用例"><a href="#4-5-测试用例" class="headerlink" title="4.5 测试用例"></a>4.5 测试用例</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.bind.annotation.RequestMapping;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.bind.annotation.RestController;</span><br><span class="line"></span><br><span class="line"><span class="meta">@RestController</span></span><br><span class="line"><span class="meta">@RequestMapping(&quot;/hbase&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HbaseController</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> HBaseUtils hBaseUtils;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 创建表</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@author</span> suyuan</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@date</span> 2021/6/22 17:17 </span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@RequestMapping(&quot;/createTable&quot;)</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">createTable</span><span class="params">()</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line">        String[] arr = &#123;<span class="string">&quot;name&quot;</span>,<span class="string">&quot;age&quot;</span>&#125;;</span><br><span class="line">        hBaseUtils.createTable(<span class="string">&quot;sy:syy&quot;</span>,arr);</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;ok&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 删除表</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@author</span> suyuan</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@date</span> 2021/6/22 17:18 </span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@RequestMapping(&quot;/deleteTable&quot;)</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">deleteTable</span><span class="params">()</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line">        hBaseUtils.deleteTable(<span class="string">&quot;syy&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;ok&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 插入记录(插入同列族数据就是更新)</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@author</span> suyuan</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@date</span> 2021/6/22 17:18 </span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@RequestMapping(&quot;/insertRecords&quot;)</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">insertRecords</span><span class="params">()</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line">        hBaseUtils.insertRecords(<span class="string">&quot;sy:syy&quot;</span>,<span class="string">&quot;20210622&quot;</span>,<span class="string">&quot;name&quot;</span>, <span class="keyword">new</span> String[]&#123;<span class="string">&quot;name1&quot;</span>,<span class="string">&quot;name2&quot;</span>&#125;, <span class="keyword">new</span> String[]&#123;<span class="string">&quot;111&quot;</span>,<span class="string">&quot;222&quot;</span>&#125;);</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;ok&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 查找一行记录</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@author</span> suyuan</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@date</span> 2021/6/22 17:18 </span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@RequestMapping(&quot;/selectRow&quot;)</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">selectRow</span><span class="params">()</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line">        String s = hBaseUtils.selectRow(<span class="string">&quot;sy:syy&quot;</span>, <span class="string">&quot;20210622&quot;</span>);</span><br><span class="line">        System.out.println(s);</span><br><span class="line">        <span class="keyword">return</span> s;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h1 id="本地编写代码需配置"><a href="#本地编写代码需配置" class="headerlink" title="本地编写代码需配置:"></a>本地编写代码需配置:</h1><h2 id="host地址"><a href="#host地址" class="headerlink" title="host地址"></a>host地址</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">192.168.10.160  master</span><br><span class="line">192.168.10.161  slave1</span><br><span class="line">192.168.10.162  slave2</span><br></pre></td></tr></table></figure>
<h2 id="集群需要启动"><a href="#集群需要启动" class="headerlink" title="集群需要启动"></a>集群需要启动</h2><p>zookeeper、hadoop、hbase<br><img src="https://gitee.com/symkmk123/pic-go/raw/master/img/20210622172514.png" class="lazyload placeholder" data-srcset="https://gitee.com/symkmk123/pic-go/raw/master/img/20210622172514.png" srcset="https://img2.baidu.com/it/u=2037979560,2772131037&fm=26&fmt=auto&gp=0.jpg"></p>

      </div>
      <div class="post-tags-categories">
        
        <div class="tags">
          
            <a href="/tags/Hbase/" class="">
              Hbase
            </a>
          
            <a href="/tags/%E5%A4%A7%E6%95%B0%E6%8D%AE/" class="">
              大数据
            </a>
          
        </div>
        
      </div>
      
        <div class="copyright">
  <ul class="post-copyright">
    <li class="post-copyright-author">
    <strong>作者:  </strong>symkmk123</a>
    </li>
    <li class="post-copyright-link">
    <strong>文章链接:  </strong>
    <a href="/2021/05/21/hbase/" target="_blank" title="Hbase介绍及操作">http://example.com/2021/05/21/hbase/</a>
    </li>
    <li class="post-copyright-license">
      <strong>版权声明:   </strong>
      本网站所有文章除特别声明外,均采用 <a rel="license" href="https://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank" title="Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)">CC BY-NC-ND 4.0</a>
      许可协议。转载请注明出处!
    </li>
  </ul>
<div>
      
    </article>
    <!-- 上一篇文章和下一篇文章 -->
    
      <!-- 文章详情页的上一页和下一页 -->
<div class="post-nav">



  
  <div class="post-nav-prev post-nav-item">
    <div class="post-nav-img" style="background-size: cover; 
      background-position: center center;">
      <img class="lazyload lazyload placeholder" src="/medias/4.jpg" class="lazyload placeholder" data-srcset="/medias/4.jpg" srcset="https://img2.baidu.com/it/u=2037979560,2772131037&fm=26&fmt=auto&gp=0.jpg" alt="">
    </div>
    <a href="/2021/10/20/01redis%E5%92%8Czk%E9%94%81%E7%9A%84%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86/" class="post-nav-link">
      <div class="title">
        <i class="fas fa-angle-left"></i> 上一篇:
        <div class="title-text">01redis和zk锁的实现原理</div>
      </div>
      
      <!-- <div class="content">
        01_基于redis和zookeeper的分布式锁实现原理1、面试题
一般实现分布式锁都有哪些方式？使用redis如何设
      </div> -->
    </a>
  </div>



  
  <div class="post-nav-next post-nav-item">
    <div class="post-nav-img" style="background-size: cover; 
      background-position: center center;">
      <img class="lazyload lazyload placeholder" src="/medias/9.jpg" class="lazyload placeholder" data-srcset="/medias/9.jpg" srcset="https://img2.baidu.com/it/u=2037979560,2772131037&fm=26&fmt=auto&gp=0.jpg" src="" alt="">
    </div>
    <a href="/2021/05/21/mybatis-plus%E6%80%BB%E7%BB%93/" class="post-nav-link">
      <div class="title">
        下一篇: <i class="fas fa-angle-right"></i>
        <div class="title-text">mybatis-plus总结</div>
      </div>
      <!-- <div class="content">
        mybatis-plus自定义分页、SQL+wrapper一起使用123456789101112131415161718
      </div> -->
    </a>
  </div>

</div>

    
    

    <!-- 打赏 -->
    

    <!-- 分享 -->
    
    
    <!-- 评论 -->
    <!-- 评论 -->

  <div id="myComment">
    
      <div id="gitment-container"></div>

    
  </div>

<!-- comment script in themes\hexo-theme-bamboo\layout\_partial\scripts\index.ejs -->


  </div>

  <!-- 目录 -->
  <!-- 文章详情页右侧目录 -->

  <div class="toc-aside">
    <div class="toc-main">
      <div class="toc-aside-title">
        <i class="fas fa-list-ul" aria-hidden="true"></i><span>本文目录</span>
        
          <div class="toc-open-close">本文目录</div>
        
      </div>
      <div class="toc-content">
        <div class="toc"></div>
      </div>
    </div>
  </div>

  <!-- 手机端目录按钮 -->
  <div id="toc-mobile-btn">
    <i class="fas fa-list-ul" aria-hidden="true"></i>
  </div>
  <!-- js在scripts目录下的的toc.ejs里面 -->
  

  <script>
    function openBtnClickFn () {
      let openOrCloseBtn = $('.toc-aside .toc-aside-title .toc-open-close');
      let open = eval('' || 'true');
      openOrCloseBtn.click(function() {
        if (open === true) {
          $(".toc-aside").css({'width': 0, 'padding': 0});
          $(".toc-content").css({'width': 0});
          $(".toc-aside-title span, .toc-aside-title i").css({'display': 'none'});
          $(".main-content").css({'width': '75%', 'margin': '10px auto'});
          open = false;
        } else {
          $(".toc-aside").css({'width': '300px', 'padding': '0 10px'});
          $(".toc-content").css({'width': '300px'});
          $(".toc-aside-title span, .toc-aside-title i").css({'display': 'inline-block'});
          $(".main-content").css({'width': '65%', 'margin-right': '10px', 'margin-left': 'calc(35% - 350px)'});
          open = true;
        }
      });
    };
    openBtnClickFn();
    document.addEventListener('pjax:complete', function () {
      openBtnClickFn();
    })
    
  </script>


  <!-- 图片放大 Wrap images with fancybox support -->
  <script src="/js/wrapImage.js"></script>
</div>

<!-- 文章详情页背景图 -->
<div id="appBgSwiper" style="position: fixed;left: 0;top: 0;width: 100%;height: 100%;z-index: -2;"
	:style="{'background-color': bgColor ? bgColor : 'transparent'}">
	<transition-group tag="ul" :name="names">
		<li v-for='(image,index) in img' :key='index' v-show="index === mark" class="bg-swiper-box">
			<img :src="image" class="bg-swiper-img no-lazy">
		</li>
	</transition-group>
</div>
<script>
	var vm = new Vue({
		el: '#appBgSwiper',
		data: {
			names: '' || 'fade' || 'fade', // translate-fade fade
			mark: 0,
			img: [],
			bgColor: '',
			time: null
		},
		methods: {   //添加方法
			change(i, m) {
				if (i > m) {
					// this.names = 'fade';
				} else if (i < m) {
					// this.names = 'fade';
				} else {
					return;
				}
				this.mark = i;
			},
			prev() {
				// this.names = 'fade';
				this.mark--;
				if (this.mark === -1) {
					this.mark = 3;
					return
				}
			},
			next() {
				// this.names = 'fade';
				this.mark++;
				if (this.mark === this.img.length) {
					this.mark = 0;
					return
				}
			},
			autoPlay() {
				// this.names = 'fade';
				this.mark++;
				if (this.mark === this.img.length) {
					this.mark = 0;
					return
				}
			},
			play() {
				let bgImgDelay = '' || '180000'
				let delay = parseInt(bgImgDelay) || 180000;
				this.time = setInterval(this.autoPlay, delay);
			},
			enter() {
				clearInterval(this.time);
			},
			leave() {
				this.play();
			}
		},
		created() {
			this.play()
		},
		beforeDestroy() {
			clearInterval(this.time);
		},
		mounted() {
			let prop = '' || '';
			let isImg = prop.includes('.bmp') || prop.includes('.jpg') || prop.includes('.png') || prop.includes('.tif') || prop.includes('.gif') || prop.includes('.pcx') || prop.includes('.tga') || prop.includes('.exif') || prop.includes('.fpx') || prop.includes('.psd') || prop.includes('.cdr') || prop.includes('.pcd') || prop.includes('.dxf') || prop.includes('.ufo') || prop.includes('.eps') || prop.includes('.ai') || prop.includes('.raw') || prop.includes('.WMF') || prop.includes('.webp') || prop.includes('.jpeg') || prop.includes('http://') || prop.includes('https://')
			if (isImg) {
				let img = prop.split(',');
				let configRoot = '/'
				let arrImg = [];
				img.forEach(el => {
					var Expression = /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/;
					var objExp = new RegExp(Expression);

					if (objExp.test(el)) {
						// http or https
						arrImg.push(el);
					} else {
						// 非http or https开头
						// 本地文件
						let firstStr = el.charAt(0);
						if (firstStr == '/') {
							el = el.substr(1); // 删除第一个字符 '/',因为 configRoot最后一个字符为 /
						}
						el = configRoot + el;
						arrImg.push(el);
					}
				})
				this.img = arrImg;
			} else {
				this.bgColor = prop;
			}
		}
	})
</script>

<style>
	.bg-swiper-box {
		position: absolute;
		display: block;
		width: 100%;
		height: 100%;
	}

	.bg-swiper-img {
		object-fit: cover;
		width: 100%;
		height: 100%;
	}
</style>




  <script>
  function loadMermaid() {
    if (document.getElementsByClassName('mermaid').length) {
      if (window.mermaidJsLoad) mermaid.init()
      else {
        loadScript('https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js').then(() => {
          window.mermaidJsLoad = true
          mermaid.initialize({
            theme: 'default',
          })
          if ('true') {
            mermaid.init();
          }
        })
      }
    }
  };
  document.addEventListener("DOMContentLoaded", function () {
    loadMermaid();
  })

  document.addEventListener('pjax:complete', function () {
    loadMermaid();
  })
  
</script>


      </main>
    </div>

    <!-- 页脚 -->
    
  
  <div class="footer bg-color">
    <div class="footer-main">
      
        
          <div class="link">
            
          </div>
        
      
        
          <div class="footer-copyright">
            <p>Copyright © 2019 - 2020 <a target="_blank" rel="noopener" href="https://github.com/yuang01">yuang01</a> | Powered by <a target="_blank" rel="noopener" href="https://hexo.io/zh-cn/docs/">Hexo</a> | Theme <a target="_blank" rel="noopener" href="https://github.com/yuang01/theme">Bamboo</a> </p>

          </div>
        
      
        
          
            <!-- 不蒜子统计 -->
            <!-- 不蒜子统计 -->
<span id="busuanzi_container_site_pv">
      <i class="fas fa-eye" aria-hidden="true"></i>本站总访问量：<span id="busuanzi_value_site_pv"></span> 次
</span>
<span class="post-meta-divider">|</span>
<span id="busuanzi_container_site_uv" style='display:none'>
      <i class="fas fa-users" aria-hidden="true"></i>本站访客数：<span id="busuanzi_value_site_uv"></span> 人
</span>

          
        
      
        
          <div class="footer-custom">
            
          </div>
        
      
    </div>
  </div>



    <!-- 渲染暗黑按钮 -->
    
      <div class="dark">
  <div class="dark-content">
    <i class="fas fa-moon" aria-hidden="true"></i>
    <!-- <span>关灯</span> -->
  </div>
  
</div>

<script>
  $(function() {
    let isDark = JSON.parse(localStorage.getItem('dark'))  || JSON.parse('false');
    if (isDark) {
      $(".dark-content").replaceWith(
          `
          <div class='dark-content'>
            <i class="fas fa-lightbulb" aria-hidden="true"></i>
          </div>
          `
        );
    }
    $('.dark').click(function() {
      if ($(document.body).is('.darkModel')) {
        $(document.body).removeClass('darkModel');
        localStorage.setItem('dark', false);
        $(".dark-content").replaceWith(
          `
          <div class='dark-content'>
            <i class="fas fa-moon" aria-hidden="true"></i>
          </div>
          `
        );
      } else {
        $(document.body).addClass('darkModel');
        localStorage.setItem('dark', true);
        $(".dark-content").replaceWith(
          `
          <div class='dark-content'>
            <i class="fas fa-lightbulb" aria-hidden="true"></i>
          </div>
          `
        );
      }
    })
  })
</script>
    
    <!-- 渲染回到顶部按钮 -->
    
      <div class="goTop top-btn-color" pointer>
  <i class="fas fa-arrow-up" aria-hidden="true"></i>
</div>
<script src="/js/goTop.js"></script>

    
    <!-- 渲染左下角音乐播放器 -->
    

    <!-- 图片放大 -->
    
      <script src="/js/fancybox/jquery.fancybox.min.js"></script>
    

    <!-- 百度解析 -->
    <!-- Baidu Analytics -->

    <!-- Baidu Push -->

<script>
    (function () {
        var bp = document.createElement('script');
        var curProtocol = window.location.protocol.split(':')[0];
        if (curProtocol === 'https') {
            bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
        } else {
            bp.src = 'http://push.zhanzhang.baidu.com/push.js';
        }
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(bp, s);
    })();
</script>

    
    <!-- 背景彩带 -->
    
      <script type="text/javascript" size="100" alpha='0.4' zIndex="-1" src="/js/ribbon.min.js"></script>
    

    <script src="/js/utils/index.js"></script>
    <script src="/js/app.js" data-pjax></script>
    
    <!-- 文章目录所需js -->
<link href="/js/tocbot/tocbot.css" rel="stylesheet">
<script src="/js/tocbot/tocbot.min.js"></script>

<script>
  var headerEl = 'h1,h2, h3, h4',  //headers 
    content = '.post-detail',//文章容器
    idArr = {};  //标题数组以确定是否增加索引id
  //add #id
  var option = {
    // Where to render the table of contents.
    tocSelector: '.toc',
    // Where to grab the headings to build the table of contents.
    contentSelector: content,
    // Which headings to grab inside of the contentSelector element.
    headingSelector: headerEl,
    scrollSmooth: true,
    scrollSmoothOffset: -80,
    headingsOffset: -($(window).height() * 0.4 - 45),
    positionFixedSelector: '.toc-main',
    positionFixedClass: 'is-position-fixed',
    fixedSidebarOffset: 'auto',
    activeLinkClass: 'is-active-link',
    // onClick: function (e) {},
  }
  if ($('.toc').length > 0) {

    $(content).children(headerEl).each(function () {
      //去除空格以及多余标点
      var headerId = $(this).text().replace(/[\s|\~|`|\!|\@|\#|\$|\%|\^|\&|\*|\(|\)|\_|\+|\=|\||\|\[|\]|\{|\}|\;|\:|\"|\'|\,|\<|\.|\>|\/|\?|\：|\，|\。]/g, '');

      headerId = headerId.toLowerCase();
      if (idArr[headerId]) {
        //id已经存在
        $(this).attr('id', headerId + '-' + idArr[headerId]);
        idArr[headerId]++;
      }
      else {
        //id未存在
        idArr[headerId] = 1;
        $(this).attr('id', headerId);
      }
    });

    document.addEventListener("DOMContentLoaded", function () {
      tocbot.init(option);
      mobileTocClick();
    });

  }

  window.tocScrollFn = function () {
    return bamboo.throttle(function () {
      findHeadPosition();
    }, 100)()
  }
  window.addEventListener('scroll', tocScrollFn);

  const findHeadPosition = function (top) {
    if ($('.toc-list').length <= 0) {
      return false;
    }
    setTimeout(() => {  // or DOMContentLoaded 
      autoScrollToc();
    }, 0);
  }

  const autoScrollToc = function () {
    const $activeItem = document.querySelector('.is-active-link');
    const $cardToc = document.querySelector('.toc-content');
    const activePosition = $activeItem.getBoundingClientRect().top
    const sidebarScrollTop = $cardToc.scrollTop
    if (activePosition > (document.documentElement.clientHeight - 100)) {
      $cardToc.scrollTop = sidebarScrollTop + 150
    }
    if (activePosition < 100) {
      $cardToc.scrollTop = sidebarScrollTop - 150
    }
  }

  document.addEventListener('pjax:send', function () {
    if ($('.toc').length) {
      tocbot.destroy();
    }
  });

  document.addEventListener('pjax:complete', function () {
    if ($('.toc').length) {
      tocbot.init(option);
      mobileTocClick();
    }
  });
  
  // 手机端toc按钮点击出现目录
  const mobileTocClick = function () {
    const $cardTocLayout = document.getElementsByClassName('toc-aside')[0];
    const $cardToc = $cardTocLayout.getElementsByClassName('toc-content')[0];
    let right = '45px';
    if (window.innerWidth >= 551 && window.innerWidth <= 992) {
      right = '100px'
    }
    const mobileToc = {
      open: () => {
        $cardTocLayout.style.cssText = 'animation: toc-open .3s; opacity: 1; right: ' + right
      },

      close: () => {
        $cardTocLayout.style.animation = 'toc-close .2s'
        setTimeout(() => {
          $cardTocLayout.style.cssText = "opacity:''; animation: ''; right: ''"
        }, 100)
      }
    }
    document.getElementById('toc-mobile-btn').addEventListener('click', () => {
      if (window.getComputedStyle($cardTocLayout).getPropertyValue('opacity') === '0') mobileToc.open()
      else mobileToc.close()
    })

    $cardToc.addEventListener('click', (e) => {
      if (window.innerWidth < 992) { // 小于992px的时候
        mobileToc.close()
      }
    })
  }
</script>

<style>
  .is-position-fixed {
    position: sticky !important;
    top: 74px;
  }

  .toc-main ul {
    counter-reset: show-list;
  }

  .toc-main ul li::before {
    content: counter(item)".";
    display: block;
    position: absolute;
    left: 12px;
    top: 0;
  }
</style> 

<!-- 渲染issues标签里的内容 -->
<script>
  function loadIssuesJS() {
    if ($(".post-detail").find(".issues-api").length == 0) {
      return;
    } 
    loadScript('/js/issues/index.js');
  };
  $(function () {
    loadIssuesJS();
  });
  document.addEventListener('pjax:complete', function () {
    if (typeof IssuesAPI == "undefined") {
      loadIssuesJS();
    }
  })
</script>

<!-- 输入框打字特效 -->
<!-- 输入框打字特效 -->

  <script src="/js/activate-power-mode.js"></script>
  <script>
    POWERMODE.colorful = true;  // 打开随机颜色特效
    POWERMODE.shake = false;    // 关闭输入框抖动
    document.body.addEventListener('input', POWERMODE);//监听打字事件
  </script>


<!-- markdown代码一键复制功能 -->

  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/v-plugs-ayu/lib/ayu.css">
  <script src="https://cdn.jsdelivr.net/npm/v-plugs-ayu/lib/ayu.umd.min.js"></script>
  <script src="/js/clipboard/clipboard.min.js"></script>
  <div id="appCopy">
  </div>
  <script data-pjax>
    var vm = new Vue({
      el: '#appCopy',
      data: {
      },
      computed: {
      },
      mounted() {
        const that = this;
        var copy = '复制';
        /* code */
        var initCopyCode = function () {
          var copyHtml = '';
          copyHtml += '<button class="btn-copy" data-clipboard-snippet="" style="position:absolute;top:0;right:0;z-index:1;">';
          copyHtml += '<i class="fas fa-copy"></i><span>' + copy + '</span>';
          copyHtml += '</button>';
          $(".post-detail pre").not('.gutter pre').wrap("<div class='codeBox' style='position:relative;width:100%;'></div>")
          $(".post-detail pre").not('.gutter pre').before(copyHtml);
          new ClipboardJS('.btn-copy', {
            target: function (trigger) {
              return trigger.nextElementSibling;
            }
          });
        }
        initCopyCode();
        $('.btn-copy').unbind('click').bind('click', function () {
          doSomething();
        })
        $(document).unbind('keypress').bind('keypress', function (e) {
          if (e.ctrlKey && e.keyCode == 67) {
            doSomething();
          }
        })

        function doSomething() {
          that.$notify({
            title: "成功",
            content: "代码已复制，请遵守相关授权协议。",
            type: 'success'
          })
        }
      },
      methods: {
      },
      created() { }
    })
  </script>
  

<!-- 图片懒加载 -->
<script defer src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@17.1.0/dist/lazyload.min.js"></script>
<script>
  // https://www.npmjs.com/package/vanilla-lazyload
  // Set the options globally
  // to make LazyLoad self-initialize
  window.lazyLoadOptions = {
    elements_selector: ".lazyload",
    threshold: 0
  };
  // Listen to the initialization event
  // and get the instance of LazyLoad
  window.addEventListener(
    "LazyLoad::Initialized",
    function (event) {
      window.lazyLoadInstance = event.detail.instance;
    },
    false
  );
  document.addEventListener('DOMContentLoaded', function () {
    lazyLoadInstance.update();
  });
  document.addEventListener('pjax:complete', function () {
    lazyLoadInstance.update();
  });
</script>


<!-- 卡片滚动动画 -->
   

<!-- 评论所需js -->

  
    <script type="text/javascript">
  var utteranceCommon = {};

  function check_utterance() {
    let isDark = JSON.parse(localStorage.getItem('dark')) || JSON.parse('false');
    if (isDark) {
      utteranceCommon.Theme = 'github-dark';
    } else {
      utteranceCommon.Theme = 'github-light';
    }

    return document.getElementById("gitment-container");
  }
  comment_el = '#gitment-container';
  load_utterance = function () {
    if ($(comment_el).length) {
      // 匿名函数，防止污染全局变量
      const HEAD = check_utterance();

      var utterances = document.createElement('script');
      utterances.type = 'text/javascript';
      utterances.async = true;
      utterances.setAttribute('issue-term', 'pathname')
      utterances.setAttribute('theme', utteranceCommon.Theme)
      utterances.setAttribute('repo', '')
      utterances.crossorigin = 'anonymous';
      utterances.src = 'https://utteranc.es/client.js';
      // content 是要插入评论的地方
      document.getElementById('gitment-container').appendChild(utterances);

    }
  }

  function dark_utterance() {
    const HEAD = check_utterance();
    if (!HEAD) return;
    const message = {
      type: 'set-theme',
      theme: utteranceCommon.Theme
    };
    const utteranceIframe = document.querySelector('iframe');
    utteranceIframe.contentWindow.postMessage(message, 'https://utteranc.es');
  }

  $(document).ready(load_utterance);
  document.addEventListener('pjax:complete', function () {
    load_utterance();
  });

  $('.dark').click(function () {
    setTimeout(() => {
      dark_utterance();
    });
  })

</script>

<style>
  .utterances {
    max-width: inherit !important;
  }
</style>
  


<!-- 鼠标点击特效 -->
<!-- 爱心点击 -->

  
    <script src="/js/cursor/text.js"></script>
  




  <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" data-pjax></script>


    <!-- pjax -->
    

<!-- pjax -->


  <script src="/js/pjax@0.2.8/index.js"></script>
  
    <!-- 样式位于：source/css/_third-party/pjaxanimate.styl -->

<div class="pjax-animate">
  
    <div class="loading-circle"><div id="loader-circle"></div></div>
    <script>
      window.ShowLoading = function() {
        $(".loading-circle").css("display", "block");
      };
      window.HideLoading = function() {
        $(".loading-circle").css("display", "none");
      }
    </script>
  
	<script>
    document.addEventListener('pjax:complete', function () {
      window.HideLoading();
    })
    document.addEventListener('pjax:send', function () {
      window.ShowLoading();
    })
    document.addEventListener('pjax:error', function () {
      window.HideLoading();
    })
	</script>
</div>

  

  <script>
    var pjax = new Pjax({
      elements: 'a[href]:not([href^="#"]):not([href="javascript:void(0)"]):not([no-pjax])',   // 拦截正常带链接的 a 标签
      selectors: ["#pjax-container","title"],                                   // 根据实际需要确认重载区域
      cacheBust: false,   // url 地址追加时间戳，用以避免浏览器缓存
      timeout: 5000
    });

    document.addEventListener('pjax:send', function (e) {

      try {
        var currentUrl = window.location.pathname;
        var targetUrl = e.triggerElement.href;
        var banUrl = [""];
        if (banUrl[0] != "") {
          banUrl.forEach(item => {
            if(currentUrl.indexOf(item) != -1 || targetUrl.indexOf(item) != -1) {
              window.location.href = targetUrl;
            }
          });
        }
      } catch (error) {}

      $(window).unbind('resize');
      $(window).unbind('scroll');
      $(document).unbind('scroll');
      $(document).unbind('click');
      $('body').unbind('click');

    })
    
    document.addEventListener('pjax:complete', function () {
      $('script[data-pjax], .pjax-reload script').each(function () {
        $(this).parent().append($(this).remove());
      });
    });

    document.addEventListener('pjax:error', function (e) {
      window.location.href = e.triggerElement.href;
    })
    
    // 刷新不从顶部开始
    document.addEventListener("DOMContentLoaded", function () {
      history.scrollRestoration = 'auto';
    })
  </script>



  </body>
</html>